package com.ibeeking.found.upms.g.rest.service.impl;

import com.ibeeking.found.upms.g.rest.service.*;
import com.ibeeking.found.common.enums.PublishStatusEnum;
import com.ibeeking.found.upms.api.common.dto.RoleResourceDTO;
import com.ibeeking.found.upms.g.rest.service.*;
import com.ibeeking.found.upms.service.common.bo.PermissionResourceBO;
import com.ibeeking.found.upms.service.common.bo.ResourceBO;
import com.ibeeking.found.upms.service.common.bo.RolePermissionBO;
import com.ibeeking.found.upms.service.common.bo.GmcUserRoleBO;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.data.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName GmcRoleResourceServiceImpl
 * @Description 角色资源
 * @Author ibeeking
 * @Date 2020-12-14 11:53
 **/
@Service
public class GmcRoleResourceServiceImpl implements IGmcRoleResourceService {

    @Resource
    private IGmcUserRoleService userRoleServiceImpl;
    @Resource
    private IGmcRolePermissionService rolePermissionServiceImpl;
    @Resource
    private IGmcPermissionResourceService permissionResourceServiceImpl;
    @Resource
    private IGmcResourceService resourceServiceImpl;

    @Override
    public List<RoleResourceDTO> queryRoleResourceByUserId(Long userId) {
        //根据用户ID查询用户角色
        List<GmcUserRoleBO> gmcUserRoleBos = userRoleServiceImpl.queryUserRoleByUserId(userId);
        if (Collections3.isEmpty(gmcUserRoleBos)) {
            return Collections3.emptyList();
        }
        //根据角色ID查询权限菜单
        List<RolePermissionBO> rolePermissionBos = rolePermissionServiceImpl.queryRolePermissionByRoleIds(gmcUserRoleBos.parallelStream().map(GmcUserRoleBO::getRoleId).distinct().collect(Collectors.toList()));
        if (Collections3.isEmpty(rolePermissionBos)) {
            return Collections3.emptyList();
        }
        //根据菜单查询资源
        List<PermissionResourceBO> permissionResourceBos = permissionResourceServiceImpl.queryPermissionResourceByPermissionIds(rolePermissionBos.parallelStream().map(RolePermissionBO::getPermissionId).distinct().collect(Collectors.toList()));
        if (Collections3.isEmpty(permissionResourceBos)) {
            return Collections3.emptyList();
        }
        //角色权限根据角色id分组
        Map<Long, List<RolePermissionBO>> rolePermissionGroupMap = rolePermissionBos.parallelStream().collect(Collectors.groupingBy(RolePermissionBO::getRoleId));
        //权限资源根据权限id分组
        Map<Long, List<PermissionResourceBO>> permissionResourceGroupMap = permissionResourceBos.parallelStream().collect(Collectors.groupingBy(PermissionResourceBO::getPermissionId));

        List<RoleResourceDTO> result = new ArrayList<>();
        for (Map.Entry<Long, List<RolePermissionBO>> entry : rolePermissionGroupMap.entrySet()) {
            RoleResourceDTO resourceDTO = new RoleResourceDTO();
            resourceDTO.setRoleId(entry.getKey());
            List<String> paths = new ArrayList<>();
            entry.getValue().stream().forEach(rolePermissionBO -> {
                List<PermissionResourceBO> resourceBOS = permissionResourceGroupMap.get(rolePermissionBO.getPermissionId());
                if (!Collections3.isEmpty(resourceBOS)) {
                    resourceBOS.stream().forEach(permissionResourceBO -> {
                        ResourceBO resourceBO = resourceServiceImpl.queryById(permissionResourceBO.getResourceId());
                        if (null != resourceBO && PublishStatusEnum.ENABLE.getValue().equals(resourceBO.getPublishStatus()) && !paths.contains(resourceBO.getResource())) {
                            StringBuffer sb = new StringBuffer(resourceBO.getResource());
                            Integer level = resourceBO.getLevel();
                            Long pId = resourceBO.getParentId();
                            while (level > 0) {
                                ResourceBO resourceBO1 = resourceServiceImpl.queryById(pId);
                                if (null == resourceBO1 || StringUtils.isBlank(resourceBO1.getResource())) {
                                    level = 0;
                                } else {
                                    sb.insert(0, resourceBO1.getResource());
                                    pId = resourceBO1.getParentId();
                                }
                                --level;
                            }
                            paths.add(sb.toString());
                        }
                    });
                }
            });
            resourceDTO.setResources(paths);
            result.add(resourceDTO);
        }
        return result;
    }
}
